package opensearchext

import (
	"context"
	"encoding/json"
	"net/http"
	"strings"

	opensearchapi "github.com/opensearch-project/opensearch-go/opensearchapi"
)

type IndexPatterns struct {
	Title         string   `json:"title,omitempty"`
	Fields        []string `json:"fields,omitempty"`
	TimeFieldName string   `json:"timeFieldName,omitempty"`
}

type CreateIndexPatternsRequest struct {
	Attribute IndexPatterns `json:"attributes,omitempty"`

	Header http.Header

	ctx context.Context
}

func (i IndexPatterns) MarshalJSON() ([]byte, error) {
	ipMap := make(map[string]interface{})
	ipMap["title"] = i.Title
	ipMap["timeFieldName"] = i.TimeFieldName
	if len(i.Fields) > 0 {
		ipMap["fields"] = i.Fields
	}
	return json.Marshal(ipMap)
}

func (c CreateIndexPatternsRequest) MarshalJSON() ([]byte, error) {
	cipMap := make(map[string]interface{})
	cipMap["attributes"] = c.Attribute
	return json.Marshal(cipMap)
}

func (c CreateIndexPatternsRequest) Do(ctx context.Context, transport opensearchapi.Transport) (*opensearchapi.Response, error) {
	var (
		method string
		path   strings.Builder
	)

	method = "POST"
	//api/saved_objects/index-pattern
	path.Grow(len("/api/saved_objects/index-pattern"))
	path.WriteString("/api/saved_objects/index-pattern")

	reqBody, err := json.Marshal(c)
	if err != nil {
		return nil, err
	}
	body := strings.NewReader(string(reqBody))

	req, err := newRequest(method, path.String(), body)
	if err != nil {
		return nil, err
	}
	if body != nil {
		req.Header[headerContentType] = []string{headerContentTypeJSON}
		req.Header[headerOsdxsrf] = []string{"true"}
	}

	if len(c.Header) > 0 {
		if len(req.Header) == 0 {
			req.Header = c.Header
		} else {
			for k, vv := range c.Header {
				for _, v := range vv {
					req.Header.Add(k, v)
				}
			}
		}
	}

	if ctx != nil {
		req = req.WithContext(ctx)
	}

	res, err := transport.Perform(req)
	if err != nil {
		return nil, err
	}

	response := opensearchapi.Response{
		StatusCode: res.StatusCode,
		Body:       res.Body,
		Header:     res.Header,
	}

	return &response, nil
}
